5ba86ca2540de234facef51e5fbe1921f4d356de,router/java/src/net/i2p/router/transport/udp/PacketBuilder.java,PacketBuilder,buildSessionConfirmedPacket,#OutboundEstablishState#number#number#number#,730
Before Change
*/
public UDPPacket buildSessionConfirmedPacket(OutboundEstablishState state, int fragmentNum, int numFragments, byte identity[]) {
UDPPacket packet = buildPacketHeader(SESSION_CONFIRMED_FLAG_BYTE);
byte data[] = packet.getPacket().getData();
int off = HEADER_SIZE;
InetAddress to = null;
try {
to = InetAddress.getByAddress(state.getSentIP());
} catch (UnknownHostException uhe) {
if (_log.shouldLog(Log.ERROR))
_log.error("How did we think this was a valid IP? " + state.getRemoteHostId().toString());
packet.release();
return null;
}
// now for the body
data[off] |= fragmentNum << 4;
data[off] |= (numFragments & 0xF);
off++;
int curFragSize = MAX_IDENTITY_FRAGMENT_SIZE;
if (fragmentNum == numFragments-1) {
if (identity.length % MAX_IDENTITY_FRAGMENT_SIZE != 0)
curFragSize = identity.length % MAX_IDENTITY_FRAGMENT_SIZE;
}
DataHelper.toLong(data, off, 2, curFragSize);
off += 2;
int curFragOffset = fragmentNum * MAX_IDENTITY_FRAGMENT_SIZE;
System.arraycopy(identity, curFragOffset, data, off, curFragSize);
off += curFragSize;
if (fragmentNum == numFragments - 1) {
DataHelper.toLong(data, off, 4, state.getSentSignedOnTime());
off += 4;
int paddingRequired = 0;
// we need to pad this so we're at the encryption boundary
if ( (off + Signature.SIGNATURE_BYTES) % 16 != 0)
paddingRequired += 16 - ((off + Signature.SIGNATURE_BYTES) % 16);
// add an arbitrary number of 16byte pad blocks too...
for (int i = 0; i < paddingRequired; i++) {
data[off] = (byte)_context.random().nextInt(255);
off++;
}
// BUG: NPE here if null signature
System.arraycopy(state.getSentSignature().getData(), 0, data, off, Signature.SIGNATURE_BYTES);
off += Signature.SIGNATURE_BYTES;
} else {
// nothing more to add beyond the identity fragment, though we can
// pad here if we want. maybe randomized?
// pad up so we're on the encryption boundary
// TODO: why not random data?
if ( (off % 16) != 0)
off += 16 - (off % 16);
}
packet.getPacket().setLength(off);
authenticate(packet, state.getCipherKey(), state.getMACKey());
setTo(packet, to, state.getSentPort());
After Change
*/
private UDPPacket buildSessionConfirmedPacket(OutboundEstablishState state, int fragmentNum, int numFragments, byte identity[]) {
UDPPacket packet = buildPacketHeader(SESSION_CONFIRMED_FLAG_BYTE);
DatagramPacket pkt = packet.getPacket();
byte data[] = pkt.getData();
int off = HEADER_SIZE;
InetAddress to = null;
try {
to = InetAddress.getByAddress(state.getSentIP());
} catch (UnknownHostException uhe) {
if (_log.shouldLog(Log.ERROR))
_log.error("How did we think this was a valid IP? " + state.getRemoteHostId().toString());
packet.release();
return null;
}
// now for the body
data[off] |= fragmentNum << 4;
data[off] |= (numFragments & 0xF);
off++;
int curFragSize = MAX_IDENTITY_FRAGMENT_SIZE;
if (fragmentNum == numFragments-1) {
if (identity.length % MAX_IDENTITY_FRAGMENT_SIZE != 0)
curFragSize = identity.length % MAX_IDENTITY_FRAGMENT_SIZE;
}
DataHelper.toLong(data, off, 2, curFragSize);
off += 2;
int curFragOffset = fragmentNum * MAX_IDENTITY_FRAGMENT_SIZE;
System.arraycopy(identity, curFragOffset, data, off, curFragSize);
off += curFragSize;
if (fragmentNum == numFragments - 1) {
DataHelper.toLong(data, off, 4, state.getSentSignedOnTime());
off += 4;
// we need to pad this so we're at the encryption boundary
int mod = (off + Signature.SIGNATURE_BYTES) & 0x0f;
if (mod != 0) {
int paddingRequired = 16 - mod;
// add an arbitrary number of 16byte pad blocks too ???
_context.random().nextBytes(data, off, paddingRequired);
off += paddingRequired;
}
// BUG: NPE here if null signature
System.arraycopy(state.getSentSignature().getData(), 0, data, off, Signature.SIGNATURE_BYTES);
off += Signature.SIGNATURE_BYTES;
} else {
// We never get here (see above)
// nothing more to add beyond the identity fragment
// pad up so we're on the encryption boundary
off = pad1(data, off);
}
off = pad2(data, off);
pkt.setLength(off);
authenticate(packet, state.getCipherKey(), state.getMACKey());
setTo(packet, to, state.getSentPort());